package cz.khfotbal.beans;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import javax.faces.context.FacesContext;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import cz.khfotbal.beans.ExportTablesBean.DifferenceComparator;
import cz.khfotbal.beans.ExportTablesBean.HomeGoalsComparator;
import cz.khfotbal.beans.ExportTablesBean.PointsComparator;
import cz.khfotbal.dao.ArticleDao;
import cz.khfotbal.dao.DownloadDao;
import cz.khfotbal.dao.SeasonCompetionDao;
import cz.khfotbal.dao.TableDao;
import cz.khfotbal.domain.Competion;
import cz.khfotbal.domain.FrontTable;
import cz.khfotbal.domain.Match;
import cz.khfotbal.domain.Season;
import cz.khfotbal.domain.SeasonCompetion;
import cz.khfotbal.domain.Team;
import cz.khfotbal.service.CompetionService;
import cz.khfotbal.service.GenerateFrontService;
import cz.khfotbal.service.MatchService;
import cz.khfotbal.service.SeasonService;
import cz.khfotbal.service.TeamService;
import cz.khfotbal.utils.GenerateFrontTable;
import cz.khfotbal.utils.KHFotbalUtils;

@Component
@Scope(value = "session")
public class GenerateFrontBean {
	
	@Autowired
	private SeasonCompetionDao seasonCompetionDao;
	@Autowired
	private TeamService teamService;
	@Autowired
	private MatchService matchService;
	@Autowired
	private TableDao tableDao;
	@Autowired
	private SeasonService seasonService;
	@Autowired
	private CompetionService competionService;
	@Autowired
	private GenerateFrontService generateFrontService;
	
	private Season selectedSeason;
	private Competion selectedCompetion;
	private List<Match> matchFilteredList = new ArrayList<Match>();
	private List<Team> teamList = new ArrayList<Team>();
	
	public Team getTeamFromListById(int id) {
		for (Team t : teamList) {
			if (t.getId() == id)
				return t;
		}
		return null;
	}
	
	public void startGenerationTable(){
		
		tableDao.deleteAll();
		
		List<Season> seasons = seasonService.getAllSeasons();
		for (Season season : seasons) {
			selectedSeason = season;
		}

		List<Competion> competions = competionService.getAllCompetions();
		for (Competion competion : competions) {
			selectedCompetion = competion;

			matchFilteredList = matchService.getMatchesBySeasonAndCompetion(
					selectedSeason, selectedCompetion);

			teamList = teamService.getTeamsBySeasonAndCompetion(selectedSeason,
					selectedCompetion);
			for (Match match : matchFilteredList) {
				if ((match.getHomeTeamScore() != null && match
						.getAwayTeamScore() != null)
						&& (KHFotbalUtils.isInteger(match.getHomeTeamScore()) && (KHFotbalUtils
								.isInteger(match.getAwayTeamScore())))) {
					getTeamFromListById(match.getHomeTeam().getId())
							.getResultData().setMatches(
									getTeamFromListById(
											match.getHomeTeam().getId())
											.getResultData().getMatches() + 1);
					getTeamFromListById(match.getAwayTeam().getId())
							.getResultData().setMatches(
									getTeamFromListById(
											match.getAwayTeam().getId())
											.getResultData().getMatches() + 1);
					getTeamFromListById(match.getHomeTeam().getId())
							.getResultData().setScoredGoals(
									getTeamFromListById(
											match.getHomeTeam().getId())
											.getResultData().getScoredGoals()
											+ Integer.valueOf(match
													.getHomeTeamScore()));
					getTeamFromListById(match.getAwayTeam().getId())
							.getResultData().setScoredGoals(
									getTeamFromListById(
											match.getAwayTeam().getId())
											.getResultData().getScoredGoals()
											+ Integer.valueOf(match
													.getAwayTeamScore()));
					getTeamFromListById(match.getHomeTeam().getId())
							.getResultData().setCollectedGoals(
									getTeamFromListById(
											match.getHomeTeam().getId())
											.getResultData()
											.getCollectedGoals()
											+ Integer.valueOf(match
													.getAwayTeamScore()));
					getTeamFromListById(match.getAwayTeam().getId())
							.getResultData().setCollectedGoals(
									getTeamFromListById(
											match.getAwayTeam().getId())
											.getResultData()
											.getCollectedGoals()
											+ Integer.valueOf(match
													.getHomeTeamScore()));
					if (Integer.valueOf(match.getHomeTeamScore()) > Integer
							.valueOf(match.getAwayTeamScore())) {
						getTeamFromListById(match.getHomeTeam().getId())
								.getResultData()
								.setPoints(
										getTeamFromListById(
												match.getHomeTeam().getId())
												.getResultData().getPoints() + 3);
						getTeamFromListById(match.getHomeTeam().getId())
								.getResultData().setWins(
										getTeamFromListById(
												match.getHomeTeam().getId())
												.getResultData().getWins() + 1);
						getTeamFromListById(match.getAwayTeam().getId())
								.getResultData().setLoss(
										getTeamFromListById(
												match.getAwayTeam().getId())
												.getResultData().getLoss() + 1);
					}
					if (Integer.valueOf(match.getHomeTeamScore()) < Integer
							.valueOf(match.getAwayTeamScore())) {
						getTeamFromListById(match.getAwayTeam().getId())
								.getResultData()
								.setPoints(
										getTeamFromListById(
												match.getAwayTeam().getId())
												.getResultData().getPoints() + 3);
						getTeamFromListById(match.getHomeTeam().getId())
								.getResultData().setLoss(
										getTeamFromListById(
												match.getHomeTeam().getId())
												.getResultData().getLoss() + 1);
						getTeamFromListById(match.getAwayTeam().getId())
								.getResultData().setWins(
										getTeamFromListById(
												match.getAwayTeam().getId())
												.getResultData().getWins() + 1);
					}
					if (Integer.valueOf(match.getHomeTeamScore()) == Integer
							.valueOf(match.getAwayTeamScore())) {
						getTeamFromListById(match.getHomeTeam().getId())
								.getResultData()
								.setPoints(
										getTeamFromListById(
												match.getHomeTeam().getId())
												.getResultData().getPoints() + 1);
						getTeamFromListById(match.getAwayTeam().getId())
								.getResultData()
								.setPoints(
										getTeamFromListById(
												match.getAwayTeam().getId())
												.getResultData().getPoints() + 1);
						getTeamFromListById(match.getHomeTeam().getId())
								.getResultData()
								.setDraws(
										getTeamFromListById(
												match.getHomeTeam().getId())
												.getResultData().getDraws() + 1);
						getTeamFromListById(match.getAwayTeam().getId())
								.getResultData()
								.setDraws(
										getTeamFromListById(
												match.getAwayTeam().getId())
												.getResultData().getDraws() + 1);
					}

				}

			}

			Collections.sort(teamList, new HomeGoalsComparator());
			Collections.sort(teamList, new DifferenceComparator());
			Collections.sort(teamList, new PointsComparator());
			for (int i = 0; i < teamList.size(); i++) {
				teamList.get(i).getResultData().setPosition(i + 1);
			}

			exportToFile();
		}


	}

	public void exportToFile() {		
		
		SeasonCompetion sc = seasonCompetionDao.findSeasonCopetionBySeasonIdAndCometionId(selectedSeason.getId(),
				selectedCompetion.getId());	
		
			for (Team team : teamList) {
				String teamFrontName = "";
				if (team.getFrontName() == null) {
					teamFrontName = "";
				} else {
					teamFrontName = team.getFrontName();
				}
				FrontTable frontTable = new FrontTable();
				frontTable.setSeasonCompetionId(sc.getId());
				frontTable.setPoradi(team.getResultData().getPosition());
				frontTable.setTym(teamFrontName);
				frontTable.setZapasy(team.getResultData().getMatches());
				frontTable.setVyhry(team.getResultData().getWins());
				frontTable.setRemizy(team.getResultData().getDraws());
				frontTable.setProhry(team.getResultData().getLoss());
				frontTable.setVstreleneGoly(team.getResultData().getScoredGoals());
				frontTable.setObdrzeneGoly(team.getResultData().getCollectedGoals());
				frontTable.setBody(team.getResultData().getPoints());
				tableDao.saveTable(frontTable);				
			}
	}
	
	
	public void updateOneCompetion(){
		generateFrontService.updateOneCompetion(4);
	}
	
	public void generateMatches(){
		generateFrontService.generateMatches();
	}
	
		
	public class PointsComparator implements Comparator<Team> {
		public int compare(Team t1, Team t2) {
			return (t2.getResultData().getPoints() - t1.getResultData()
					.getPoints());
		}

	}

	public class DifferenceComparator implements Comparator<Team> {
		public int compare(Team t1, Team t2) {
			return ((t2.getResultData().getScoredGoals() - t2.getResultData()
					.getCollectedGoals()) - (t1.getResultData()
					.getScoredGoals() - t1.getResultData().getCollectedGoals()));
		}

	}

	public class HomeGoalsComparator implements Comparator<Team> {
		public int compare(Team t1, Team t2) {
			return (t2.getResultData().getScoredGoals() - t1.getResultData()
					.getScoredGoals());
		}

	}	
	

}
